package com.view.cn.mvprxjava.fragment.socket;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.view.cn.mvprxjava.R;
import com.view.cn.mvprxjava.fragment.BaseFragment;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;

/**
 * 服务端socket
 * Created by Zengxiaoping on 2017/2/9.
 */

public class ServiceSocketFragment extends BaseFragment implements View.OnClickListener {

	public static final String TAG = ServiceSocketFragment.class.getSimpleName();

	private TextView tvIP;
	private TextView tv;
	private EditText etSendContent;
	private Button btnAccept;
	private Button btnSend;

	//存放客户端连接的ip和通信socket
	private ArrayMap<String, Socket> mArrayMap = new ArrayMap<>();
	private ServerSocket mServerSocket;
	private boolean isConnect;
	private AcceptThread mAcceptThread;
	private ReceiveThread mReceiveThread;
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
				//建立链接
				case 0:
					tvIP.setText("已建立连接" + new String((byte[]) msg.obj));
					break;
				//发送数据
				case 1:
					tv.setText(msg.obj != null ? msg.obj.toString() : "连接已断开");
					break;
			}
		}
	};

	public static ServiceSocketFragment newInstance() {
		ServiceSocketFragment fragment = new ServiceSocketFragment();
		return fragment;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}

	@Nullable
	@Override
	public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.fragment_service, container, false);
		initView(view);
		return view;
	}

	private void initView(View view) {
		tvIP = (TextView) view.findViewById(R.id.tvIP);
		tv = (TextView) view.findViewById(R.id.tv);
		etSendContent = (EditText) view.findViewById(R.id.etSendContent);
		btnAccept = (Button) view.findViewById(R.id.btnAccept);
		btnSend = (Button) view.findViewById(R.id.btnSend);

		btnAccept.setOnClickListener(this);
		btnSend.setOnClickListener(this);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		mHandler.removeCallbacksAndMessages(null);//清空消息队列，防止Handler强引用导致内存泄漏
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
			//服务器接收到数据
			case R.id.btnAccept:
				isConnect = true;
				if (mAcceptThread == null) {
					mAcceptThread = new AcceptThread();
					mAcceptThread.start();
				}
				break;
			//服务器发送数据
			case R.id.btnSend:
				String msg = etSendContent.getText().toString() + "\n";
				//给所有的客户端发送消息
				Iterator<String> clientIps = mArrayMap.keySet().iterator();
				while (clientIps.hasNext()) {
					sendMessage(clientIps.next(), msg);
				}
				break;
		}
	}

	//发送消息给指定ip的客户端
	private void sendMessage(String clientIp, String msg) {
		Socket socket = mArrayMap.get(clientIp);               //拿到制定客户端的sock
		OutputStream outputStream = null;
		try {
			if (socket != null && socket.isConnected()) {
				outputStream = socket.getOutputStream();       //获得socket的输出流
				outputStream.write(msg.getBytes());
				outputStream.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//定义监听客户端连接的线程
	private class AcceptThread extends Thread {
		@Override
		public void run() {

			try {
				mServerSocket = new ServerSocket(40002);   //建立一个ServerSocket服务器端
			} catch (IOException e) {
				e.printStackTrace();
			}

			while (isConnect) {
				Socket socket = null;
				try {
					socket = mServerSocket.accept();           //阻塞直到有socket客户端连接
				} catch (IOException e) {
					e.printStackTrace();
				}

				if (socket != null && socket.isConnected()) {
					Message message = mHandler.obtainMessage();
					message.what = 0;
					message.obj = socket.getInetAddress().getAddress();//获取客户端IP地址
					mHandler.sendMessage(message);

					//加入缓存
					if (mArrayMap.containsKey(socket.getInetAddress().getHostAddress())) {
						mArrayMap.remove(socket.getInetAddress().getHostAddress().toString());
						mArrayMap.put(socket.getInetAddress().getHostAddress().toString(), socket);
					} else {
						mArrayMap.put(socket.getInetAddress().getHostAddress().toString(), socket);
					}
					//开启线程接收数据
					mReceiveThread = new ReceiveThread(socket);
					mReceiveThread.start();
				}
			}
		}
	}

	//定义一个接收数据的线程
	private class ReceiveThread extends Thread {

		private Socket socket;
		private InputStream mInputStream;
		private String read;

		public ReceiveThread(Socket socket) {
			try {
				this.socket = socket;
				mInputStream = socket.getInputStream();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			while (socket.isConnected()) {
				BufferedReader bufferedReader = null;
				try {
					bufferedReader = new BufferedReader(new InputStreamReader(mInputStream, "UTF-8"));
					read = bufferedReader.readLine();//读服务器端发来的数据，阻塞直到收到结束符\n或\r
				} catch (Exception e) {
					e.printStackTrace();
				}

				//用Handler把读取到的信息发到主线程
				Message message = mHandler.obtainMessage();
				message.what = 1;
				message.obj = read;
				mHandler.sendMessage(message);
			}
		}
	}
}

